/**
 * 
 */
package net.toocruel.iqismart.service.core.impl;


import net.toocruel.iqismart.dao.UserRepository;
import net.toocruel.iqismart.dao.core.*;
import net.toocruel.iqismart.entity.constants.SourceType;
import net.toocruel.iqismart.entity.core.*;
import net.toocruel.iqismart.entity.rbac.User;
import net.toocruel.iqismart.service.core.SupportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;

/**
 * @author toocruel
 *
 */
@Service
@Transactional
public class SupportServiceImpl implements SupportService {
    @Autowired
    private TagRepository tagRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private SupportRepository supportRepository;

    @Autowired
    private QuestionRepository questionRepository;

    @Autowired
    private AnswerRepository answerRepository;

    @Autowired
    private CommentRepository commentRepository;

    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public String support(User user, SourceType sourceType, Long sourceId) {
        Support one = supportRepository.findOne((root, query, cb) -> {
            Predicate predicateUser = cb.equal(root.get("user"), user);
            Predicate source = null;
            switch (sourceType) {
                case question:
                    Question question = questionRepository.findOne(sourceId);
                    question.setSupportNum(question.getSupportNum()-1>0?question.getSupportNum()-1:0);
                    questionRepository.save(question);
                    source = cb.equal(root.get("question"), question);
                    break;
                case answer:
                    Answer answer = answerRepository.findOne(sourceId);
                    answer.setSupportNum(answer.getSupportNum()-1>0?answer.getSupportNum()-1:0);
                    answerRepository.save(answer);
                    source = cb.equal(root.get("answer"), answer);
                    break;
                case comment:
                    Comment comment = commentRepository.findOne(sourceId);
                    comment.setSupportNum(comment.getSupportNum()-1>0?comment.getSupportNum()-1:0);
                    commentRepository.save(comment);
                    source = cb.equal(root.get("comment"), comment);
                    break;
                case article:
                    Article article = articleRepository.findOne(sourceId);
                    article.setSupportNum(article.getSupportNum()-1>0?article.getSupportNum()-1:0);
                    articleRepository.save(article);
                    source = cb.equal(root.get("article"), article);
                    break;

            }
            return cb.and(predicateUser, source);
        });

        if(one!=null){
            supportRepository.delete(one);
            return "unsupported";
        }

        Support support = new Support();
        support.setSourceType(sourceType);
        switch (sourceType){
            case question:
                Question question = questionRepository.findOne(sourceId);
                question.setSupportNum(question.getSupportNum()+1);
                questionRepository.save(question);
                support.setQuestion(question);
                support.setToUser(question.getUser());
                break;
            case answer:
                Answer answer = answerRepository.findOne(sourceId);
                answer.setSupportNum(answer.getSupportNum()+1);
                answerRepository.save(answer);
                support.setAnswer(answer);
                support.setToUser(answer.getUser());
                break;
            case comment:
                Comment comment = commentRepository.findOne(sourceId);
                comment.setSupportNum(comment.getSupportNum()+1);
                commentRepository.save(comment);
                support.setComment(comment);
                support.setToUser(comment.getUser());
                break;
            case article:
                support.setArticle(articleRepository.findOne(sourceId));
                break;

        }
        support.setUser(user);

        supportRepository.save(support);


        return "supported";
    }

    @Override
    public String chech(User user,SourceType sourceType, Long sourceId) {
        Support one = supportRepository.findOne((root, query, cb) -> {
            Predicate predicateUser = cb.equal(root.get("user"), user);
            Predicate source = null;
            switch (sourceType) {
                case question:
                    source = cb.equal(root.get("question"), questionRepository.findOne(sourceId));
                    break;
                case answer:
                    source = cb.equal(root.get("answer"), answerRepository.findOne(sourceId));
                    break;
                case comment:
                    source = cb.equal(root.get("comment"), commentRepository.findOne(sourceId));
                    break;
                case article:
                    source = cb.equal(root.get("article"), articleRepository.findOne(sourceId));
                    break;

            }
            return cb.and(predicateUser, source);
        });

        if(one!=null){
            return "failed";
        }

        return "success";
    }
}
